package ar.edu.unq.leezsi.requestcycle;

import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import ar.edu.unq.leezsi.exception.CowebRuntimeException;
import ar.edu.unq.leezsi.html.ComponentAdaptor;
import ar.edu.unq.leezsi.html.ComponentConfigurator;
import ar.edu.unq.leezsi.html.Page;
import ar.edu.unq.leezsi.utils.ClassUtils;
import ar.edu.unq.leezsi.utils.ClassWrapper;
import ar.edu.unq.leezsi.utils.ResponseWriter;

public class HTTPDispatcher {

	private RequestActionType getRequestActionType(String requestURI) {
		return RequestActionType.value(requestURI);
	}

	public void resolve(HttpServletRequest request,
			HttpServletResponse response, FilterChain chain,
			RequestCycle requestCycle) {
		String requestURI = request.getRequestURI().replaceAll(
				request.getContextPath() + "/", "");
		String[] parts = requestURI.split("/");
		String uri = requestURI.replace(parts[0] + "/", "");
		RequestActionType actionType = this.getRequestActionType(parts[0]);
		try {
			switch (actionType) {
			case PAGE:
				final InternalRequestParams internalRequestParams = new InternalRequestParams(
						requestURI);
				ClassWrapper<Page<?>> wrapperForName;
				try {
					wrapperForName = ClassUtils
							.<Page<?>> wrapperForName(internalRequestParams
									.getPageClass());
				} catch (Exception e) {
					throw new CowebRuntimeException("Page "
							+ internalRequestParams.getPageClass()
							+ " not found");
				}
				Page<?> page = wrapperForName.newInstance();
				requestCycle.setPage(page);
				new ComponentConfigurator(requestCycle.getContext())//
						.configure(page)//
						.render(page, response);
				break;
			case ACTION:
				new ComponentAdaptor(requestCycle.getPage())
						.executeAction(new HTTPAction(uri));
				break;
			case RESOURCE:
				String mime = "text/html";
				if (parts[2].endsWith("js")) {
					mime = "text/javascript";
				}
				new ResponseWriter(response).setMime(mime).write(
						ClassUtils.wrapperForName(parts[1])
								.getResourceAsStream(parts[2]));
				break;
			case SERVER_CONTENT:
				requestCycle.doChain(request, response, chain);
				break;
			}
		} catch (Exception e) {
			new ResponseWriter(response).writeException(e);
		}
	}
}
